home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / download.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  9KB  |  358 lines

  1. /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    $Id: download.c,v 1.56 2001/02/15 08:39:45 drscholl Exp $ */
  6.  
  7. #include <string.h>
  8. #include "opennap.h"
  9. #include "debug.h"
  10.  
  11. /* 203 [ :<sender> ] <nick> "<filename>" */
  12. /* 500 [ :<sender> ] <nick> "<filename>" */
  13. /* handle client request for download of a file */
  14. HANDLER (download)
  15. {
  16.     char   *av[2], *sender_name;
  17.     USER   *user, *sender;
  18.     DATUM  *info = 0;
  19.     int     ac = -1;
  20.  
  21.     (void) len;
  22.     ASSERT (validate_connection (con));
  23.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  24.     return;
  25.     if (pkt)
  26.     ac = split_line (av, sizeof (av) / sizeof (char *), pkt);
  27.  
  28.     if (ac < 2)
  29.     {
  30.     unparsable (con);
  31.     return;
  32.     }
  33.  
  34.     /* find the user to download from */
  35.     user = hash_lookup (Users, av[0]);
  36.     if (!user)
  37.     {
  38.     send_user (sender, MSG_SERVER_SEND_ERROR, "%s \"%s\"", av[0], av[1]);
  39.     return;
  40.     }
  41.  
  42.     /* if the user holding the requested file is local... */
  43.     if (ISUSER (user->con))
  44.     {
  45.     if (is_ignoring (user->con->uopt->ignore, sender->nick))
  46.     {
  47.         send_user (sender, MSG_SERVER_NOSUCH, "%s is ignoring you",
  48.                user->nick);
  49.         return;
  50.     }
  51.  
  52.     /* check to make sure the user is actually sharing this file */
  53.     info = hash_lookup (user->con->uopt->files, av[1]);
  54.     if (!info)
  55.     {
  56.         send_user (sender, MSG_SERVER_SEND_ERROR, "%s \"%s\"",
  57.                user->nick, av[1]);
  58.         return;
  59.     }
  60.     }
  61.  
  62.     if (tag == MSG_CLIENT_DOWNLOAD)
  63.     {
  64.     if (user->port == 0)
  65.     {
  66.         /* uploader is firewalled, send file info so that downloader can
  67.            send the 500 request */
  68.         if (ISUSER (user->con))
  69.         {
  70.         ASSERT (info != 0);
  71.         send_user (sender, MSG_SERVER_FILE_READY /* 204 */ ,
  72.                "%s %u %hu \"%s\" %s %d", user->nick,
  73.                user->ip, user->port, av[1],
  74. #if RESUME
  75.                info->hash,
  76. #else
  77.                "00000000000000000000000000000000",
  78. #endif
  79.                user->speed);
  80.         }
  81.         else
  82.         {
  83.         /* not a local user, we have to relay this request since we
  84.            dont' have the file information local.  route it directly
  85.            to the server we know this user is behind. */
  86.         ASSERT (ISSERVER (user->con));
  87.         send_cmd (user->con, tag, ":%s %s \"%s\"", sender->nick,
  88.               user->nick, av[1]);
  89.         }
  90.         return;
  91.     }
  92.     }
  93.     else
  94.     {
  95.     ASSERT (tag == MSG_CLIENT_DOWNLOAD_FIREWALL);
  96.     if (user->port != 0)
  97.     {
  98.         /* this user is not firewalled */
  99.         send_user (sender, MSG_SERVER_NOSUCH, "%s is not firewalled",
  100.                user->nick);
  101.         return;
  102.     }
  103.     if (sender->port == 0)
  104.     {
  105.         /* error, both clients are firewalled */
  106.         ASSERT (ISUSER (con));
  107.         send_cmd (con, MSG_SERVER_FILE_READY /* 204 */ ,
  108.               "%s %u %hu \"%s\" firewallerror %d",
  109.               user->nick, user->ip, user->port, av[1], user->speed);
  110.         return;
  111.     }
  112.     }
  113.  
  114.     /* if the client holding the file is a local user, send the request
  115.        directly */
  116.     if (ISUSER (user->con))
  117.     {
  118.     send_cmd (user->con, MSG_SERVER_UPLOAD_REQUEST, "%s \"%s\"",
  119.           sender->nick, av[1]);
  120.     }
  121.     /* otherwise pass it to the peer servers for delivery */
  122.     else
  123.     {
  124.     /* don't use direct delivery here because the server the client is
  125.        connected to needs to consult their db and rewrite this messsage */
  126.     send_cmd (user->con, MSG_SERVER_UPLOAD_REQUEST, ":%s %s \"%s\"",
  127.           sender->nick, user->nick, av[1]);
  128.     }
  129. }
  130.  
  131. static USER *
  132. transfer_count_wrapper (CONNECTION * con, char *pkt, int numeric)
  133. {
  134.     USER   *user;
  135.  
  136.     ASSERT (validate_connection (con));
  137.     if (pop_user (con, &pkt, &user))
  138.     return 0;
  139.     /* relay to peer servers */
  140.     pass_message_args (con, numeric, ":%s", user->nick);
  141.     return user;
  142. }
  143.  
  144. /* 220 [ :<user> ] */
  145. HANDLER (upload_start)
  146. {
  147.     USER   *user;
  148.  
  149.     (void) tag;
  150.     (void) len;
  151.     ASSERT (validate_connection (con));
  152.     user = transfer_count_wrapper (con, pkt, MSG_CLIENT_UPLOAD_START);
  153.     if (!user)
  154.     return;
  155.     ASSERT (validate_user (user));
  156.     user->uploads++;
  157.     user->totalup++;
  158. }
  159.  
  160. /* 221 [ :<user> ] */
  161. HANDLER (upload_end)
  162. {
  163.     USER   *user;
  164.  
  165.     (void) tag;
  166.     (void) len;
  167.     ASSERT (validate_connection (con));
  168.     user = transfer_count_wrapper (con, pkt, MSG_CLIENT_UPLOAD_END);
  169.     if (!user)
  170.     return;
  171.     ASSERT (validate_user (user));
  172.     if (user->uploads > 0)
  173.     user->uploads--;
  174. }
  175.  
  176. /* 218 [ :<user> ] */
  177. HANDLER (download_start)
  178. {
  179.     USER   *user;
  180.  
  181.     (void) tag;
  182.     (void) len;
  183.     ASSERT (validate_connection (con));
  184.     user = transfer_count_wrapper (con, pkt, MSG_CLIENT_DOWNLOAD_START);
  185.     if (!user)
  186.     return;
  187.     ASSERT (validate_user (user));
  188.     user->downloads++;
  189.     user->totaldown++;
  190. }
  191.  
  192. /* 219 [ :<user> ] */
  193. HANDLER (download_end)
  194. {
  195.     USER   *user;
  196.  
  197.     (void) tag;
  198.     (void) len;
  199.     ASSERT (validate_connection (con));
  200.     user = transfer_count_wrapper (con, pkt, MSG_CLIENT_DOWNLOAD_END);
  201.     if (!user)
  202.     return;
  203.     ASSERT (validate_user (user));
  204.     if (user->downloads > 0)
  205.     user->downloads--;
  206. }
  207.  
  208. /* 600 <user> */
  209. /* client is requesting the link speed of <user> */
  210. HANDLER (user_speed)
  211. {
  212.     USER   *user;
  213.  
  214.     (void) tag;
  215.     (void) len;
  216.     CHECK_USER_CLASS ("user_speed");
  217.     user = hash_lookup (Users, pkt);
  218.     if (!user)
  219.     {
  220.     nosuchuser (con);
  221.     return;
  222.     }
  223.     ASSERT (validate_user (user));
  224.     send_cmd (con, MSG_SERVER_USER_SPEED /* 601 */ , "%s %d",
  225.           user->nick, user->speed);
  226. }
  227.  
  228. /* 626 [ :<nick> ] <user> */
  229. /* client is notifying other party of a failure to connect to their data
  230.    port */
  231. HANDLER (data_port_error)
  232. {
  233.     USER   *sender, *user;
  234.  
  235.     (void) tag;
  236.     (void) len;
  237.  
  238.     ASSERT (validate_connection (con));
  239.     if (pop_user (con, &pkt, &sender) != 0)
  240.     return;
  241.     ASSERT (validate_user (sender));
  242.     user = hash_lookup (Users, pkt);
  243.     if (!user)
  244.     {
  245.     nosuchuser (con);
  246.     return;
  247.     }
  248.     ASSERT (validate_user (user));
  249.  
  250.     /* we pass this message to all servers so the mods can see it */
  251.     pass_message_args (con, tag, ":%s %s", sender->nick, user->nick);
  252.  
  253.     notify_mods
  254.     (PORTLOG_MODE,
  255.      "Notification from %s: %s (%s) - configured data port %hu is unreachable.",
  256.      sender->nick, user->nick, my_ntoa (BSWAP32 (user->ip)), user->port);
  257.  
  258.     /* if local, notify the target of the error */
  259.     if (user->local)
  260.     send_cmd (user->con, tag, "%s", sender->nick);
  261. }
  262.  
  263. /* 607 :<sender> <recip> "<filename>" [speed] */
  264. HANDLER (upload_request)
  265. {
  266.     char   *av[3], *sender_name;
  267.     USER   *recip, *sender;
  268.     int     ac = -1;
  269.  
  270.     (void) tag;
  271.     (void) len;
  272.  
  273.     ASSERT (validate_connection (con));
  274.     CHECK_SERVER_CLASS ("upload_request");
  275.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  276.     return;
  277.     if (pkt)
  278.     ac = split_line (av, sizeof (av) / sizeof (char *), pkt);
  279.  
  280.     if (ac < 2)
  281.     {
  282.     log ("upload_request: too few args");
  283.     return;
  284.     }
  285.     recip = hash_lookup (Users, av[0]);
  286.     if (!recip)
  287.     {
  288.     log ("upload_request: %s: no such user", av[0]);
  289.     return;
  290.     }
  291.     ASSERT (validate_user (recip));
  292.  
  293.     /* if local user, deliver the message */
  294.     if (ISUSER (recip->con))
  295.     {
  296.     /* make sure the user is actually sharing this file */
  297.     DATUM  *info = hash_lookup (recip->con->uopt->files, av[1]);
  298.  
  299.     if (!info)
  300.     {
  301.         log ("upload_request: %s is not sharing %s", recip->nick, av[1]);
  302.         return;
  303.     }
  304.     send_cmd (recip->con, MSG_SERVER_UPLOAD_REQUEST /* 607 */ ,
  305.           "%s \"%s\" %d", sender->nick, av[1], sender->speed);
  306.     }
  307.     else
  308.     {
  309.     /* route the request to the server which the uploader is behind */
  310.     send_cmd (recip->con, MSG_SERVER_UPLOAD_REQUEST,
  311.           ":%s %s \"%s\" %d", sender->nick, recip->nick, av[1],
  312.           sender->speed);
  313.     }
  314. }
  315.  
  316. /* 619 <nick> <filename> <limit> */
  317. HANDLER (queue_limit)
  318. {
  319.     char   *av[3];
  320.     int     ac;
  321.     USER   *recip;
  322.     DATUM  *info;
  323.  
  324.     (void) tag;
  325.     (void) len;
  326.     ASSERT (validate_connection (con));
  327.     CHECK_USER_CLASS ("queue_limit");
  328.     ac = split_line (av, sizeof (av) / sizeof (char *), pkt);
  329.  
  330.     if (ac != 3)
  331.     {
  332.     log ("queue_limit(): wrong number of parameters");
  333.     print_args (ac, av);
  334.     unparsable (con);
  335.     return;
  336.     }
  337.     recip = hash_lookup (Users, av[0]);
  338.     if (!recip)
  339.     {
  340.     nosuchuser (con);
  341.     return;
  342.     }
  343.     ASSERT (validate_user (recip));
  344.     ASSERT (validate_connection (recip->con));
  345.  
  346.     /* look up the filesize in the db */
  347.     info = hash_lookup (con->uopt->files, av[1]);
  348.     if (!info)
  349.     {
  350.     send_cmd (con, MSG_SERVER_NOSUCH, "Not sharing that file");
  351.     return;
  352.     }
  353.  
  354.     /* deliver to user even if remote */
  355.     send_user (recip, MSG_SERVER_LIMIT, "%s \"%s\" %u %s",
  356.            con->user->nick, av[1], info->size, av[2]);
  357. }
  358.